package main

import (
	"bytes"
	"crypto/md5"
	"fmt"
	"io"
	"io/fs"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

var listen = make(chan bool)

var fileMap = make(map[string]string)

func main() {
	if len(os.Args) <= 1 {
		log.Fatal("请指定文件夹")
	}
	path := os.Args[1]

	if err := loadFile(path); err != nil {
		log.Fatalf("初始化目录失败:%v", err)
		return
	}
	log.Println("初始化目录完成...")

	go func() {
		for {
			log.Println("开始新的监控")
			loopListen(path)
			log.Println("监控结束,5分钟后继续扫描")
			time.Sleep(time.Minute * 5)
		}
	}()
	for {
		select {
		case <-listen:
			log.Println("开始提交git...")
			{
				log.Println("执行git add .")
				c := exec.Command("powershell", "git add .")
				c.Dir = path
				//有变化,执行git提交命令
				if _, err := c.CombinedOutput(); err == nil {
					{
						log.Println("执行git commit -m 'z'")
						c := exec.Command("powershell", "git commit -m 'z'")
						c.Dir = path
						//有变化,执行git提交命令
						if _, err := c.CombinedOutput(); err == nil {
							log.Println("执行git push")
							c := exec.Command("powershell", "git push")
							c.Dir = path
							//有变化,执行git提交命令
							c.CombinedOutput()
							log.Println("提交完成...")
						}
					}
				}
			}
		}
	}
}

func loadFile(path string) error {
	return filepath.WalkDir(path, func(p string, d fs.DirEntry, err error) error {
		if p[0] == '.' {
			return nil
		}
		if !d.IsDir() {
			md5Str, _ := GetFileMD5(p)
			fileMap[p] = md5Str
		}
		return nil
	})
}

func loopListen(path string) bool {
	path = strings.ReplaceAll(strings.ReplaceAll(path, "/", string(os.PathSeparator)), "\\", string(os.PathSeparator))
	files, err := os.ReadDir(path)
	if err != nil {
		log.Printf("读取文件夹错误:%v\n", err)
		return false
	}
	for _, file := range files {
		if file.Name()[0] == '.' {
			continue
		}
		info, _ := file.Info()
		filePath := strings.ReplaceAll(strings.ReplaceAll(fmt.Sprintf("%s/%s", path, info.Name()), "/", string(os.PathSeparator)), "\\", string(os.PathSeparator))
		if file.IsDir() {
			//继续检查
			if loopListen(filePath) {
				return true
			}
		} else {
			//文件
			modTimeStr := info.ModTime().Format("2006-01-02 15:4:05") //文件修改时间
			value, ok := fileMap[filePath]
			if ok {
				md5Str, _ := GetFileMD5(filePath)
				if value != md5Str {
					listen <- true
					log.Printf("文件:%s,有变动\n", filePath)
					return true
				}
			} else {
				fileMap[filePath] = modTimeStr
			}
		}
	}
	return false
}

func GetFileMD5(filename string) (string, error) {

	file, err := os.Open(filename)
	if err != nil {
		return "", err
	}
	defer file.Close()

	var result bytes.Buffer
	_, err = io.Copy(&result, file)
	if err != nil {
		return "", err
	}

	checksum := md5.Sum(result.Bytes())
	return fmt.Sprintf("%x", checksum), nil
}
